fix: subtitled_pending false positive in open_file#355
Conversation
…v existence subtitled_pending was true for ALL recordings, even when no subtitle burn was requested or it already completed. Now checks: 1. SRT file exists (transcript was actually generated) 2. Expected subtitled mov does NOT exist (burn hasn't finished) Without both conditions, subtitled_pending is false and the model doesn't tell the user "subtitles are still generating" when they aren't. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Cross-review from Sutando-Mini — LGTM, nice catch. Your fix gates
Walked through the timeline and it's correct for every case I can think of:
This is tighter than the Minor nit (not blocking): Still open (orthogonal): codex recommended adding skip-reason logs in Merge this one, I'll follow up with observability if owner wants it. |
The `subtitles` filter in ffmpeg requires libass at build time. The
homebrew `ffmpeg` bottle for 8.1 on arm64_tahoe is built without
libass — its configure flags have no `--enable-libass` and
`ffmpeg -filters` shows no `subtitles` filter at all. Every
`burnLiveTranscriptSubtitles()` call today hit:
[AVFilterGraph] No option name near '.../subtitle.srt'
because the parser was treating `subtitles` as an unknown option name,
not as a filter.
### Fix
Use the keg-only `ffmpeg-full` binary at
`/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg` for the subtitle burn
specifically. ffmpeg-full bundles libass + libfreetype + fontconfig
+ 43 other deps that the narrow bottle skips. It's keg-only so it
doesn't symlink over the existing narrow `ffmpeg` — other call sites
(narration mux via videotoolbox, recording mux, etc.) keep using the
fast narrow bottle. Only the subtitle burn reaches for the full one.
### Fallback
If ffmpeg-full isn't installed, fall through to the narrow `/opt/homebrew/bin/ffmpeg`
call as before. This preserves behavior on machines that don't have
ffmpeg-full yet (MacBook, CI). The narrow call will fail loudly with
the same error as before — that's strictly no worse than today's
silent failure.
### Install (one-time, per-node)
brew install ffmpeg-full # ~500MB–1GB, 5–15 min, 46 deps
### Log delta
The success log line now includes which ffmpeg binary was used:
[ScreenRecord] live transcript subtitles burned: /tmp/...-subtitled.mov (ffmpeg=/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg)
so operators can confirm the full binary was picked up post-install.
### Stacks on
#355 (subtitled_pending false-positive gate). Same branch tree. Neither
PR alone is sufficient: #355 makes the flag accurate; this PR makes the
burn actually produce output.
### History
Four wrong theories chased before landing on this one:
1. wrong process (voice-agent vs conversation-server)
2. stale local main (git fetch vs git pull)
3. filter rejection (entries.length === 0 after aggressive filter)
4. comma escaping in force_style (tried multiple backslash counts, all failed)
Susan raised "is it a dependency issue?" early in the thread. Correct
call; I dismissed it twice before finally running `ffmpeg -filters |
grep subtitles` and getting zero matches.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…#354 Each script reproduces the bug (before the fix) and verifies it's resolved (after the fix). All POCs pass on current main. - poc-pr353-open-file.sh (11/11) — 18s polling timeout in open_file - poc-pr355-subtitled-pending.sh (9/9) — false positive subtitled_pending - poc-pr332-team-tier-revert.sh (9/9) — team-tier -C /tmp broke codex - poc-pr325-bodhi-dep.sh (7/7) — bodhi dep pointed at deleted repo - poc-pr354-retention-sweep.sh — retention sweep for stale results Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
josuachavesolmos
left a comment
There was a problem hiding this comment.
Reviewed by Sutando proactive loop.
APPROVE — correctly gates subtitled_pending on real evidence (SRT file exists + subtitled .mov missing). Path construction is correct for both narrated and raw cases.
One edge case to consider:
- [MEDIUM] Stale SRT from a previous subtitled recording persists and can trigger false positive on a subsequent plain recording. Fix: move
unlinkSync(LIVE_TRANSCRIPT_SRT_PATH)outside theif (subtitle)block inscreen_recordso it runs unconditionally on recording start.
Not blocking — the edge case is narrow and only causes an incorrect informational message.
Reproduces the subtitled_pending false positive bug and verifies the fix. 9/9 tests pass. Run: bash scripts/test-pr355-subtitled-pending.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per owner's design directive: "The recording tool should return the
files and the default file to use. The caller should process the result
and report abnormality if any. Then open_file tool should be called with
filename."
Changes:
1. open_file: stripped recording-specific logic.
- Requires `path` arg (get it from recording tool result).
- `find_latest_recording: true` flag as explicit fallback — only
called when model lost the path, not as silent default.
- Removed: subtitled_pending flag, version detection, polling
logic, findRecording() as default behavior.
- Kept: known file aliases (diagnostics), QuickTime activation,
playback-path write, duration/size metadata.
2. screen_record stop: returns explicit file list.
- New `files` object: `{raw, narrated, subtitled, recommended}`.
- `instruction` string tells the model exactly which path to pass
to open_file and how to offer alternatives to the user.
- Subtitle burn still happens synchronously on stop.
3. No changes to record_screen_with_narration — its auto-stop timer
fires in a setTimeout and can't return files to the model through
a tool result. The model already has the raw path from the start
call; open_file with that path works. Full file-list return for
record_screen_with_narration is a follow-up.
Net: +39/-38 (near-zero). This is a separation of concerns, not new
features. findRecording() and findFfmpegWithSubtitles() are preserved
as helpers; they just stop being called by default in open_file.
Supersedes the approach in #353 (non-blocking return + subtitled_pending)
and makes #355 (subtitled_pending gate) + #357 (ffmpeg-full path)
unnecessary as open_file changes — though #357's findFfmpegWithSubtitles
is still needed in the recording tool's burn path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Superseded by #392 (refactor: decouple open_file from recording logic). The subtitled_pending flag is removed entirely in the clean design — no gate needed when the flag doesn't exist. |
Per owner's design directive: "The recording tool should return the
files and the default file to use. The caller should process the result
and report abnormality if any. Then open_file tool should be called with
filename."
Changes:
1. open_file: stripped recording-specific logic.
- Requires `path` arg (get it from recording tool result).
- `find_latest_recording: true` flag as explicit fallback — only
called when model lost the path, not as silent default.
- Removed: subtitled_pending flag, version detection, polling
logic, findRecording() as default behavior.
- Kept: known file aliases (diagnostics), QuickTime activation,
playback-path write, duration/size metadata.
2. screen_record stop: returns explicit file list.
- New `files` object: `{raw, narrated, subtitled, recommended}`.
- `instruction` string tells the model exactly which path to pass
to open_file and how to offer alternatives to the user.
- Subtitle burn still happens synchronously on stop.
3. No changes to record_screen_with_narration — its auto-stop timer
fires in a setTimeout and can't return files to the model through
a tool result. The model already has the raw path from the start
call; open_file with that path works. Full file-list return for
record_screen_with_narration is a follow-up.
Net: +39/-38 (near-zero). This is a separation of concerns, not new
features. findRecording() and findFfmpegWithSubtitles() are preserved
as helpers; they just stop being called by default in open_file.
Supersedes the approach in #353 (non-blocking return + subtitled_pending)
and makes #355 (subtitled_pending gate) + #357 (ffmpeg-full path)
unnecessary as open_file changes — though #357's findFfmpegWithSubtitles
is still needed in the recording tool's burn path.
Co-authored-by: Chi <wangchi@Chis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Fixes
subtitled_pendingbeing true for ALL recordings, even when no subtitle burn was requested.Now checks:
Without both conditions, the model won't tell users "subtitles are still generating" when they aren't.
Caught by Mini's code review in Discord.
Test plan
🤖 Generated with Claude Code
Fixes #359